
                 Program : SPatience
                 Purpose : To play patience?
                 Author  : J.Horsnell BSc(Hons) MSc
                 Date    : Sept 1992

  To play the game use the left button on the mouse.
  Place the pointer over a card you wish to move and press the
  button.  Now move the card to its new position, if it's a
  valid move the card will stay there, if not it will return
  home.  If you're not sure whether or not a card can go anywhere,
  click on it (if the click-fly option is set, see the menu).

  There are a few things about the application it may be good to know.
  A: Auto fly off is temporarily suspended after an UNDO .
  B: You may 'tweek' SPatience in a few ways using the environment variable
     'SPatience$Options'.
   : The automatic moving of cards is 'tweek'able to one of three states.
     All:  allows all windows to move cards around regardless of mouse.
     Pref: as 'All' but if mouse is over one, only that game will progress.
     Only: Only the window in which the mouse is will progress.
     This is done via the !Run file or via the menu entry 'state'.
   : The speed of the animation of the cards is alterable.
  C: A resignation is irreversible.  This includes the UNDO feature (etc).
  D: You may 'Deal' several times before deciding to play without fear of
     that deal being recognised as a 'Played' game.
  E: UNDO will not return the game to a 'fresh deal' position.  Thus a 
     subsequent 'Deal' will increment the 'Played' counter.



             SPatience game description language
             ***********************************


These files are used to describe the format of patience stacks on screen 
and their operation during game play.

  Before we start here are a few notes:
      
    The character '|' is used to denote a comment line.
    The whole file is case in-sensitive
    Items in square braces '[]' are optional.
    '[]' followed by *n, means it my be repeated up to n times.
    Each file can be used to describe only one game (currently).
    Most errors in the file will cause the script to be abandoned.
    Card indices start at zero.
    The game area origin is at the top left of the window.
    <exp> denotes an expression that will be evaluated using
       the function Evaluate_Expression in RISC OS.
    <str> denotes a character string with optional enclosing 
       double quotes.  If included, the string will be used as-is,
       If excluded, the string will be converted to lower case.
    <f> denotes a flag. 
    <f>* denotes a sequence of flags.
    Two identifiers have been defined (CW & CH) denoting recommended
    stack separation in the x (CW) and y (CH) directions.  They are
    mnemonics for 'Card Width' and 'Card Height'.
    Any text following the keyword END will be ignored meaning lines like
    'END STACK' and 'END DEFINE' are possible should you want to use them.


  In the beginning there were three possible commands:

  - SCRIPT_TYPE <exp>
        Only one script type is defined currently - 1.
        All others will be prosecuted.

  - DATA_BLOCK_TYPE <exp>
        Only one data block type is defined currently - 1.
        This is used to identify a saved game format.

  - BEGIN <str>
        Begins the definition of a patience window.
        <str> is used as the window title.
        This alters the command set being used to that following.

  After the BEGINning came the game commands.

  - FLAGS <f>*
        The flags possible here are:

        - ClickFly (off by default)
              Activates a game toggle that allows the user to click on a
              stack to initiate a search for somewhere else to put the 
              chosen card(s).

        - AutoFly (off by default)
              Another toggle to allow cards to search for new homes
              without the user clicking first.

        - AnimateFly (off by default)
              When cards are travelling to a new home and this flag has
              been used, the cards will travel in a series of step
              giving the illusion of animation.

  - Packs <exp> (1 by default)
        How many card packs can be used. (1 to 6 inclusive).

  - Width <exp> (1200 by default)
        Total width of the playing area. (window width)

  - Height <exp> (1800 by default)
        Total height of the playing area. (window height)

  - ZeroToWin <exp>
        Defines an expression (up to 100 characters long) that 
        will be evaluated after a players move to indicate the
        winning of the game by the player.  Evaluation of zero
        indicates a win.  To aid this there are two tokens that
        may be used:
        EMPTY$<exp>   - the number of empty stacks that have an
                        ID of <exp>
        CARDSIN$<exp> - the total number of cards in stacks that
                        have an ID of <exp>

  - Score <exp> , <exp>
        Places in the window a box containing four values:
        Played: total number of these games played so far
        Won:    total number of these games won so far
        Lost:   total number of these games lost so far
        Streak: number of games played since the last game lost

  - STACK
        Used to begin the definition of a card stack.
        See later 'Defining card stacks'.

  - FOUNDATION (a typical patience stack type)
        Same as a stack but with various flags etc overridden:
        DeepCheck, JoinSS__, PaintLast,
        AppendOneOnly, AutoClick, AutoFly
        FIRST 1, MAX 13, DragUpTo 0, JoinOffset 1
        The stack is also marked as a foundation meaning they
        will get preference when cards are click-flown.

  - FOR <identifier> = <int> TO <int>
        A simple loop definition.
        Must be incrementative.
        Nesting up to ten levels is possible.
        <identifier>'s can be up to 19 characters long.
        Any longer will cause a lot of 'Unkown operand' errors.

  - END
        Ends a FOR loop.

  And then there was bliss.


                       Defining card stacks
                       ********************

   This is effectively another command set and includes:

   X <exp>
     the X coordinate of the stack origin

   Y <exp>
     the Y coordinate of the stack origin

   First <exp> [ , <exp> ]
     defines a range of card numbers that can be put on an empty stack
     1-13 denote Ace to King
     0 denotes any cards

   MAX <exp>
     the maximum number of cards a player may put on this stack
     This has a upper-bound of 208 cards (4 packs).

   ID <exp>
     an identifier used to identify a group of stacks.
     NB: this must not be zero.

   DragUpTo <exp>
     defines an expression similar to that of 'ZeroToWin' above but
     indicates the maximum number of cards a player may drag from this
     stack

   JoinOffset <exp>
     an integer indicating what cards may be added together to form a
     stack (see also the RotateJoin flag later).
     EG.
        1 means a TWO may be placed on an ACE
        -1 means the opposite.

   DealTo <exp1> , <exp2>
     if this stack is clicked by the player, <exp2> cards will be dealt
     to all stacks with an ID of <exp1> unless this stack is empty, in 
     which case the reverse will be true (ie, <exp2> will be taken
     from..)

   TakeFrom <exp>
     overrides the 'taking from' part of 'DealTo' to take cards from 
     stacks with an ID of <exp> instead

   Deal <exp> [ , <exp1> ]*8
     Deal <exp> cards to this stack for a new game.
     Cards with an index value of <exp1> etc. will be toggled from face
     down to face up etc.

     For example:
        Deal 10 , 2 , 4 , 8
        means deal five cards,
          cards 0 & 1 will be face down
          cards 2 & 3 will be face up
          cards 4...7 will be face down
          cards 8 & 9 will be face up

   Flags <f>*
     Defines a number of stack flags
     - ShallowCheck (default)
          when joining two stacks, only check cards at the intersection
     - DeepCheck
          check all cards being appended with their neighbours
     - RotateJoin (off by default)
          Kings and Aces may be appended if allowed by other rules above.
          (depends also on the value of JoinOffset)
     - JoinSS__
          only cards with the same suit may be appended
     - JoinDS__
          only cards with a different suit....
     - JoinDSSC
          cards with a different suit but the same colour....
     - Join__DC (default)
          cards with a different colour....
     - Join__SC
          cards with the same colour....
     - PaintLast
          when painting the stack on screen only paint the last card
     - PaintDown (default)
          paint all cards downwards from the stack origin
     - PaintLeft
          paint all cards left towards the origin
     - PaintRight
          paint right from the origin
     - PaintBack
          only paint one card back
     - PaintCount
          as PaintBack but indicates how many cards are remaining
     - AutoFly (off by default)
          when auto fly is initiated, this stack can accept the cards
     - ClickFly (off by default)
          when click fly is initiated, this stack can accept the cards
     - AppendOneOnly (off by default)
          only allows one card at a time to be appended to a stack
          - useful for foundations where only one card is normally added.
     - NoAutoFly,NoClickFly,AppendAny
          reverses the above


                       Other useful information
                       ************************

  When using click or auto fly off routines, note that the destination
  is chosen with a preference for those stacks that were defined first.
  Excluding the current home of the selected cards.

  When declaring a stack as being able to receive AutoFly cards, it
  is a good idea to also ensure that the DragUpTo total is zero.
  I won't tell you why, find out for yourself.

  When storing the current game state, don't save it over the original
  script file, that can be a realy stupid thing to do.

  Games load faster if they are stored as a saved game instead of scripts
  but they use around 5-20 times the average 1k file size of script files.

  An ARM3 is realy useful.


                            Error reporting
                            ***************
  Just in case there are one or two things i've overlooked...
  Create a saved game before the offending operation if possible.
  Write down what you do to cause the error to happen.
  Place both in an envelope, seal it and burn it....
